Load the libraries
knitr::opts_knit$set(root.dir = rprojroot::find_rstudio_root_file())
knitr::opts_chunk$set(echo = TRUE)
pacman::p_load(tidyverse,vegan,GPArotation,psych,MASS,factoextra,cluster,fpc,FactoMineR,cowplot,broom,modelr,psy)
Create the curated dataset
Log transform what is needed and select the needed columns
## Parsed with column specification:
## cols(
## Species = col_character(),
## New_Species = col_character(),
## Class = col_character(),
## Order = col_character(),
## Family = col_character(),
## Max_Longevity = col_double(),
## Log_Longevity = col_double(),
## Clutch_Litter_size = col_double(),
## Mean_age_at_breeding = col_double(),
## Maximum_Broods_per_year = col_double(),
## Log_Hatchling_Mass = col_double(),
## Origin_Of_Data = col_character(),
## Log_Female_Mass = col_double()
## )
## # A tibble: 6 x 7
## Class Log_Female_Mass log_longevity log_clutch log_breading_age log_brood
## <chr> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 Amph… 0.544 0.477 2.78 -0.745 0
## 2 Amph… -0.0438 0.322 2.80 -0.523 0
## 3 Amph… 2.05 1.08 2.91 -0.301 0
## 4 Amph… 0.00303 0.477 1.29 -0.125 0
## 5 Amph… 1.61 0.322 2.86 -0.0969 0
## 6 Amph… 0.595 0.614 2.43 0 0.301
## # … with 1 more variable: Log_Hatchling_Mass <dbl>
Running the FA model and extracting the factors for 1,2, and 3 factors. And running the MFA model Storing everything in a nested dataset
#create a nested dataset with all the tetrapods
all_tetra_nest<- tetrapod_data %>%
dplyr::select(-Class) %>%
nest() %>%
add_column(Class = "Tetrapods",.before = 1)
#create a nested dataset by class, add the whole tetrapods and map the models into them
tetrapod_nested<- tetrapod_data %>%
nest(-Class) %>%
bind_rows(all_tetra_nest) %>%
mutate(model.fa1 = map(data, function(df) factanal(df,1,rotation="varimax",scores = "regression"))) %>%
mutate(model.fa2 = map(data, function(df) factanal(df,2,rotation="varimax",scores = "regression"))) %>%
mutate(model.fa3 = map(data, function(df) factanal(df,3,rotation="varimax",scores = "regression"))) %>%
mutate(model.mfa = map(data, function (df) MFA(df,group = c(1,1,1,1,1,1), type=c(rep("s",1),rep("s",1),rep("s",1),rep("s",1),rep("s",1),rep("s",1)),name.group = c("Body Size","Longevity","Clutch size","Age at breeding","Brood freq","Hatchling mass"),
ncp = 5,graph = F))) %>%
group_by(Class) %>%
mutate(model.fa1.r = map(model.fa1, function(model) broom::tidy(model)),
model.fa2.r = map(model.fa2, function(model) broom::tidy(model)),
model.fa3.r = map(model.fa3, function(model) broom::tidy(model))) %>%
mutate(model.fa1.r = map(model.fa1.r, function (df) mutate(df, com.var = 1 - uniqueness)),
model.fa2.r = map(model.fa2.r, function (df) mutate(df, com.var = 1 - uniqueness)),
model.fa3.r = map(model.fa3.r, function (df) mutate(df, com.var = 1 - uniqueness))) %>%
mutate(mfa.coord = map(model.mfa,function(mfa) mfa$quanti.var$coord[,1:3]))
# check the data
tetrapod_nested
## # A tibble: 5 x 10
## # Groups: Class [5]
## Class data model.fa1 model.fa2 model.fa3 model.mfa model.fa1.r
## <chr> <lis> <list> <list> <list> <list> <list>
## 1 Amph… <tib… <factana… <factana… <factana… <MFA> <tibble [6…
## 2 Aves <tib… <factana… <factana… <factana… <MFA> <tibble [6…
## 3 Mamm… <tib… <factana… <factana… <factana… <MFA> <tibble [6…
## 4 Rept… <tib… <factana… <factana… <factana… <MFA> <tibble [6…
## 5 Tetr… <tib… <factana… <factana… <factana… <MFA> <tibble [6…
## # … with 3 more variables: model.fa2.r <list>, model.fa3.r <list>,
## # mfa.coord <list>
Mammals
Multiple Factor Analysis (MFA)
Create the subset dataset
Check the percentage for each axis in the MFA
## [[1]]

We see that the first dimention explain most of the variation so we will plot the first and the second. Now we will explore the results.
First lets see how they disperse in space
## [[1]]

Explore the contribution of each trait to the axes
#the contribution of the first axis
pm1<- map(mammals$model.mfa,~fviz_contrib(., "group", axes = 1,title= "Contribution of traits to first axis-mammals"))
pm2<- map(mammals$model.mfa,~fviz_contrib(., "group", axes = 2,title= "Contribution of traits to second axis-mammals"))
gm1<- plot_grid(pm1[[1]],pm2[[1]],labels = c("A","B"))
gm1

Plot each point and color it based on its quality of representation
## [[1]]

Factor Analysis with factanal function
Exploratory power
We can see that in all the factors it’s quite strong exploratory power. We can use the parallel analysis to see how many factors we should use. You see that by looking at where the blue line (the actual data) breaks and where the difference between the blue line and the red line (simulated data) is the smallest. Based on this three might be more sutible but it has 0 degrees of freedom so we will take Two Factors.

## Parallel analysis suggests that the number of factors = 3 and the number of components = NA
The results for Three factors
The common variance (column com.var) shows how much of the variance is shared between a specific variable and the rest of the variables. The larger the number the more informative the variable.
## [[1]]
## # A tibble: 6 x 5
## variable uniqueness fl1 fl2 com.var
## <chr> <dbl> <dbl> <dbl> <dbl>
## 1 Log_Female_Mass 0.202 0.471 0.759 0.798
## 2 log_longevity 0.226 0.746 0.465 0.774
## 3 log_clutch 0.559 -0.520 -0.413 0.441
## 4 log_breading_age 0.106 0.872 0.367 0.894
## 5 log_brood 0.307 -0.778 -0.295 0.693
## 6 Log_Hatchling_Mass 0.005 0.349 0.934 0.995
| Log_Female_Mass |
0.2024090 |
0.4709061 |
0.7588400 |
0.7975910 |
| log_longevity |
0.2263958 |
0.7463529 |
0.4653622 |
0.7736042 |
| log_clutch |
0.5592237 |
-0.5195702 |
-0.4133064 |
0.4407763 |
| log_breading_age |
0.1055722 |
0.8717895 |
0.3666210 |
0.8944278 |
| log_brood |
0.3071465 |
-0.7781869 |
-0.2954299 |
0.6928535 |
| Log_Hatchling_Mass |
0.0050000 |
0.3493945 |
0.9343044 |
0.9950000 |
|
Factor analysis plot

Birds
Multiple Factor Analysis (MFA)
Create the subset dataset
Check the percentage for each axis in the MFA
## [[1]]

We see that the first dimention explain most of the variation so we will plot the first and the second. Now we will explore the results.
First lets see how they disperse in space
## [[1]]

Explore the contribution of each trait to the axes
#the contribution of the first axis
pm1<- map(birds$model.mfa,~fviz_contrib(., "group", axes = 1,title= "Contribution of traits to first axis-mammals"))
pm2<- map(birds$model.mfa,~fviz_contrib(., "group", axes = 2,title= "Contribution of traits to second axis-mammals"))
gm1<- plot_grid(pm1[[1]],pm2[[1]],labels = c("A","B"))
gm1

Plot each point and color it based on its quality of representation
## [[1]]

Factor Analysis with factanal function
Exploratory power
We can see that in all the factors it’s quite strong exploratory power. We can use the parallel analysis to see how many factors we should use. In our case it’s Two Factors

## Parallel analysis suggests that the number of factors = 2 and the number of components = NA
The results for Two factors
The common variance (column com.var) shows how much of the variance is shared between a specific variable and the rest of the variables. The larger the number the more informative the variable.
## [[1]]
## # A tibble: 6 x 5
## variable uniqueness fl1 fl2 com.var
## <chr> <dbl> <dbl> <dbl> <dbl>
## 1 Log_Female_Mass 0.00812 0.986 0.141 0.992
## 2 log_longevity 0.514 0.575 0.395 0.486
## 3 log_clutch 0.420 -0.125 -0.751 0.580
## 4 log_breading_age 0.160 0.542 0.739 0.840
## 5 log_brood 0.756 -0.420 -0.260 0.244
## 6 Log_Hatchling_Mass 0.0731 0.916 0.296 0.927
| Log_Female_Mass |
0.0081211 |
0.9858722 |
0.1411915 |
0.9918789 |
| log_longevity |
0.5138691 |
0.5747281 |
0.3947403 |
0.4861309 |
| log_clutch |
0.4198854 |
-0.1252311 |
-0.7512836 |
0.5801146 |
| log_breading_age |
0.1601473 |
0.5417116 |
0.7391895 |
0.8398527 |
| log_brood |
0.7561382 |
-0.4199588 |
-0.2598803 |
0.2438618 |
| Log_Hatchling_Mass |
0.0731074 |
0.9160586 |
0.2961911 |
0.9268926 |
|
Factor analysis plot

Reptiles
Multiple Factor Analysis (MFA)
Create the subset dataset
Check the percentage for each axis in the MFA
## [[1]]

We see that the first dimention explain most of the variation so we will plot the first and the second. Now we will explore the results.
First lets see how they disperse in space
## [[1]]

Explore the contribution of each trait to the axes
#the contribution of the first axis
pm1<- map(reptiles$model.mfa,~fviz_contrib(., "group", axes = 1,title= "Contribution of traits to first axis-mammals"))
pm2<- map(reptiles$model.mfa,~fviz_contrib(., "group", axes = 2,title= "Contribution of traits to second axis-mammals"))
gm1<- plot_grid(pm1[[1]],pm2[[1]],labels = c("A","B"))
gm1

Plot each point and color it based on its quality of representation
## [[1]]

Factor Analysis with factanal function
Exploratory power
We can see that in all the factors it’s quite strong exploratory power. We can use the parallel analysis to see how many factors we should use. In our case it’s Two Factors

## Parallel analysis suggests that the number of factors = 4 and the number of components = NA
The results for Two factors
The common variance (column com.var) shows how much of the variance is shared between a specific variable and the rest of the variables. The larger the number the more informative the variable.
## [[1]]
## # A tibble: 6 x 5
## variable uniqueness fl1 fl2 com.var
## <chr> <dbl> <dbl> <dbl> <dbl>
## 1 Log_Female_Mass 0.005 0.531 0.844 0.995
## 2 log_longevity 0.108 0.908 0.259 0.892
## 3 log_clutch 0.532 0.187 0.658 0.468
## 4 log_breading_age 0.274 0.762 0.380 0.726
## 5 log_brood 0.961 -0.156 -0.122 0.0392
## 6 Log_Hatchling_Mass 0.172 0.628 0.658 0.828
| Log_Female_Mass |
0.0050000 |
0.5311291 |
0.8443390 |
0.9950000 |
| log_longevity |
0.1082916 |
0.9080053 |
0.2592963 |
0.8917084 |
| log_clutch |
0.5323162 |
0.1871770 |
0.6577486 |
0.4676838 |
| log_breading_age |
0.2744691 |
0.7623471 |
0.3799387 |
0.7255309 |
| log_brood |
0.9607840 |
-0.1558700 |
-0.1219647 |
0.0392160 |
| Log_Hatchling_Mass |
0.1722643 |
0.6283427 |
0.6579677 |
0.8277357 |
|
Factor analysis plot

Amphibians
Multiple Factor Analysis (MFA)
Create the subset dataset
Check the percentage for each axis in the MFA
## [[1]]

We see that the first dimention explain most of the variation so we will plot the first and the second. Now we will explore the results.
First lets see how they disperse in space
## [[1]]

Explore the contribution of each trait to the axes
#the contribution of the first axis
pm1<- map(amph$model.mfa,~fviz_contrib(., "group", axes = 1,title= "Contribution of traits to first axis-mammals"))
pm2<- map(amph$model.mfa,~fviz_contrib(., "group", axes = 2,title= "Contribution of traits to second axis-mammals"))
gm1<- plot_grid(pm1[[1]],pm2[[1]],labels = c("A","B"))
gm1

Plot each point and color it based on its quality of representation
## [[1]]

Factor Analysis with factanal function
Exploratory power
We can see that in all the factors it’s quite strong exploratory power. We can use the parallel analysis to see how many factors we should use. In our case it’s Two Factors

## Parallel analysis suggests that the number of factors = 2 and the number of components = NA
The results for Two factors
The common variance (column com.var) shows how much of the variance is shared between a specific variable and the rest of the variables. The larger the number the more informative the variable.
In here you see that some of the variables don’t add much to the model (com.var is low)
## [[1]]
## # A tibble: 6 x 5
## variable uniqueness fl1 fl2 com.var
## <chr> <dbl> <dbl> <dbl> <dbl>
## 1 Log_Female_Mass 0.712 0.509 0.170 0.288
## 2 log_longevity 0.214 0.884 0.0708 0.786
## 3 log_clutch 0.005 -0.125 0.990 0.995
## 4 log_breading_age 0.605 0.615 -0.128 0.395
## 5 log_brood 0.883 -0.342 -0.0145 0.117
## 6 Log_Hatchling_Mass 0.871 -0.0843 -0.350 0.129
| Log_Female_Mass |
0.7116636 |
0.5094013 |
0.1698506 |
0.2883364 |
| log_longevity |
0.2139989 |
0.8837348 |
0.0707921 |
0.7860011 |
| log_clutch |
0.0050000 |
-0.1248152 |
0.9896571 |
0.9950000 |
| log_breading_age |
0.6051064 |
0.6152799 |
-0.1276403 |
0.3948936 |
| log_brood |
0.8830899 |
-0.3416131 |
-0.0145175 |
0.1169101 |
| Log_Hatchling_Mass |
0.8705508 |
-0.0842664 |
-0.3497850 |
0.1294492 |
|
Factor analysis plot

All tetrapods
Multiple Factor Analysis (MFA)
Create the subset dataset
Check the percentage for each axis in the MFA
## [[1]]

We see that the first dimention explain most of the variation so we will plot the first and the second. Now we will explore the results.
First lets see how they disperse in space
## [[1]]

Explore the contribution of each trait to the axes
#the contribution of the first axis
pm1<- map(all.tetrapods$model.mfa,~fviz_contrib(., "group", axes = 1,title= "Contribution of traits to first axis-mammals"))
pm2<- map(all.tetrapods$model.mfa,~fviz_contrib(., "group", axes = 2,title= "Contribution of traits to second axis-mammals"))
gm1<- plot_grid(pm1[[1]],pm2[[1]],labels = c("A","B"))
gm1

Plot each point and color it based on its quality of representation
## [[1]]

Factor Analysis with factanal function
Exploratory power
We can see that in all the factors it’s quite strong exploratory power. We can use the parallel analysis to see how many factors we should use. In our case it’s Two Factors

## Parallel analysis suggests that the number of factors = 3 and the number of components = NA
The results for Two factors
The common variance (column com.var) shows how much of the variance is shared between a specific variable and the rest of the variables. The larger the number the more informative the variable.
## [[1]]
## # A tibble: 6 x 5
## variable uniqueness fl1 fl2 com.var
## <chr> <dbl> <dbl> <dbl> <dbl>
## 1 Log_Female_Mass 0.181 0.520 0.741 0.819
## 2 log_longevity 0.321 0.779 0.269 0.679
## 3 log_clutch 0.777 0.0127 -0.472 0.223
## 4 log_breading_age 0.222 0.882 0.00332 0.778
## 5 log_brood 0.718 -0.459 -0.267 0.282
## 6 Log_Hatchling_Mass 0.005 0.432 0.899 0.995
| Log_Female_Mass |
0.1810837 |
0.5199908 |
0.7406257 |
0.8189163 |
| log_longevity |
0.3211015 |
0.7789730 |
0.2685122 |
0.6788985 |
| log_clutch |
0.7772686 |
0.0127173 |
-0.4717750 |
0.2227314 |
| log_breading_age |
0.2219011 |
0.8820929 |
0.0033205 |
0.7780989 |
| log_brood |
0.7178213 |
-0.4592167 |
-0.2670217 |
0.2821787 |
| Log_Hatchling_Mass |
0.0050000 |
0.4320945 |
0.8990557 |
0.9950000 |
|
Factor analysis plot

LS0tCnRpdGxlOiAiRmFjdG9yIEFuYWx5c2lzIHdpdGggZmVtYWxlIGJvZHkgbWFzcyIKYXV0aG9yOiAiTWFyaWEgTm92b3NvbG92IgpkYXRlOiAiYHIgU3lzLkRhdGUoKWAiCm91dHB1dDogCiAgaHRtbF9kb2N1bWVudDoKICAgIHRvYzogdHJ1ZQogICAgdG9jX2Zsb2F0OiB0cnVlCiAgICB0b2NfZGVwdGg6IDQKICAgIHRoZW1lOiB1bml0ZWQKICAgIGhpZ2hsaWdodDogdGFuZ28KICAgIGNvZGVfZm9sZGluZzogc2hvdwogICAgY29kZV9kb3dubG9hZDogdHJ1ZQogICAgZm9udDogRmlyYUNvZGUKLS0tCgpMb2FkIHRoZSBsaWJyYXJpZXMKYGBge3J9CmtuaXRyOjpvcHRzX2tuaXQkc2V0KHJvb3QuZGlyID0gIHJwcm9qcm9vdDo6ZmluZF9yc3R1ZGlvX3Jvb3RfZmlsZSgpKQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUpCnBhY21hbjo6cF9sb2FkKHRpZHl2ZXJzZSx2ZWdhbixHUEFyb3RhdGlvbixwc3ljaCxNQVNTLGZhY3RvZXh0cmEsY2x1c3RlcixmcGMsRmFjdG9NaW5lUixjb3dwbG90LGJyb29tLG1vZGVscixwc3kpCgpgYGAKCiMjIyBDcmVhdGUgdGhlIGN1cmF0ZWQgZGF0YXNldAoKTG9nIHRyYW5zZm9ybSB3aGF0IGlzIG5lZWRlZCBhbmQgc2VsZWN0IHRoZSBuZWVkZWQgY29sdW1ucwpgYGB7cn0Kc291cmNlKCJzY3JpcHRzL3RoZW1lX2dlb21ldHJ5LlIiKQp0ZXRyYXBvZF9kYXRhPC0gcmVhZHI6OnJlYWRfY3N2KCJkYXRhL1RldHJhcG9kIGxpZmUgaGlzdG9yeSBkYXRhYmFzZSBmb3IgbWFyaWEgMzEuMS4yMC5jc3YiKSAlPiUgCiAgZHJvcF9uYSgpICU+JSAKICBtdXRhdGUobG9nX2xvbmdldml0eSA9IGxvZzEwKE1heF9Mb25nZXZpdHkpLAogICAgICAgICBsb2dfY2x1dGNoID0gbG9nMTAoQ2x1dGNoX0xpdHRlcl9zaXplKSwKICAgICAgICAgbG9nX2JyZWFkaW5nX2FnZSA9IGxvZzEwKE1lYW5fYWdlX2F0X2JyZWVkaW5nKSwKICAgICAgICAgbG9nX2Jyb29kID0gbG9nMTAoTWF4aW11bV9Ccm9vZHNfcGVyX3llYXIpKQoKdGV0cmFwb2RfZGF0YTwtIHRldHJhcG9kX2RhdGEgJT4lIAogIGRwbHlyOjpzZWxlY3QoQ2xhc3MsIExvZ19GZW1hbGVfTWFzcywgbG9nX2xvbmdldml0eSxsb2dfY2x1dGNoLGxvZ19icmVhZGluZ19hZ2UsbG9nX2Jyb29kLExvZ19IYXRjaGxpbmdfTWFzcykKCmhlYWQodGV0cmFwb2RfZGF0YSkKCmBgYAoKUnVubmluZyB0aGUgRkEgbW9kZWwgYW5kIGV4dHJhY3RpbmcgdGhlIGZhY3RvcnMgZm9yIDEsMiwgYW5kIDMgZmFjdG9ycy4gQW5kIHJ1bm5pbmcgdGhlIE1GQSBtb2RlbApTdG9yaW5nIGV2ZXJ5dGhpbmcgaW4gYSBuZXN0ZWQgZGF0YXNldApgYGB7cn0KI2NyZWF0ZSBhIG5lc3RlZCBkYXRhc2V0IHdpdGggYWxsIHRoZSB0ZXRyYXBvZHMKYWxsX3RldHJhX25lc3Q8LSB0ZXRyYXBvZF9kYXRhICU+JSAKICBkcGx5cjo6c2VsZWN0KC1DbGFzcykgJT4lIAogIG5lc3QoKSAlPiUKICBhZGRfY29sdW1uKENsYXNzID0gIlRldHJhcG9kcyIsLmJlZm9yZSA9IDEpCgojY3JlYXRlIGEgbmVzdGVkIGRhdGFzZXQgYnkgY2xhc3MsIGFkZCB0aGUgd2hvbGUgdGV0cmFwb2RzIGFuZCBtYXAgdGhlIG1vZGVscyBpbnRvIHRoZW0KdGV0cmFwb2RfbmVzdGVkPC0gdGV0cmFwb2RfZGF0YSAlPiUKICBuZXN0KC1DbGFzcykgJT4lCiAgYmluZF9yb3dzKGFsbF90ZXRyYV9uZXN0KSAlPiUgCiAgbXV0YXRlKG1vZGVsLmZhMSA9IG1hcChkYXRhLCBmdW5jdGlvbihkZikgZmFjdGFuYWwoZGYsMSxyb3RhdGlvbj0idmFyaW1heCIsc2NvcmVzID0gInJlZ3Jlc3Npb24iKSkpICU+JSAKICBtdXRhdGUobW9kZWwuZmEyID0gbWFwKGRhdGEsIGZ1bmN0aW9uKGRmKSBmYWN0YW5hbChkZiwyLHJvdGF0aW9uPSJ2YXJpbWF4IixzY29yZXMgPSAicmVncmVzc2lvbiIpKSkgJT4lIAogIG11dGF0ZShtb2RlbC5mYTMgPSBtYXAoZGF0YSwgZnVuY3Rpb24oZGYpIGZhY3RhbmFsKGRmLDMscm90YXRpb249InZhcmltYXgiLHNjb3JlcyA9ICJyZWdyZXNzaW9uIikpKSAlPiUKICBtdXRhdGUobW9kZWwubWZhID0gbWFwKGRhdGEsIGZ1bmN0aW9uIChkZikgTUZBKGRmLGdyb3VwID0gYygxLDEsMSwxLDEsMSksIHR5cGU9YyhyZXAoInMiLDEpLHJlcCgicyIsMSkscmVwKCJzIiwxKSxyZXAoInMiLDEpLHJlcCgicyIsMSkscmVwKCJzIiwxKSksbmFtZS5ncm91cCA9IGMoIkJvZHkgU2l6ZSIsIkxvbmdldml0eSIsIkNsdXRjaCBzaXplIiwiQWdlIGF0IGJyZWVkaW5nIiwiQnJvb2QgZnJlcSIsIkhhdGNobGluZyBtYXNzIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuY3AgPSA1LGdyYXBoID0gRikpKSAlPiUgCiAgZ3JvdXBfYnkoQ2xhc3MpICU+JSAKICBtdXRhdGUobW9kZWwuZmExLnIgPSBtYXAobW9kZWwuZmExLCBmdW5jdGlvbihtb2RlbCkgYnJvb206OnRpZHkobW9kZWwpKSwgCiAgICAgICAgIG1vZGVsLmZhMi5yID0gbWFwKG1vZGVsLmZhMiwgZnVuY3Rpb24obW9kZWwpIGJyb29tOjp0aWR5KG1vZGVsKSksCiAgICAgICAgIG1vZGVsLmZhMy5yID0gbWFwKG1vZGVsLmZhMywgZnVuY3Rpb24obW9kZWwpIGJyb29tOjp0aWR5KG1vZGVsKSkpICU+JSAKICBtdXRhdGUobW9kZWwuZmExLnIgPSBtYXAobW9kZWwuZmExLnIsIGZ1bmN0aW9uIChkZikgbXV0YXRlKGRmLCBjb20udmFyID0gMSAtIHVuaXF1ZW5lc3MpKSwKICAgICAgICAgbW9kZWwuZmEyLnIgPSBtYXAobW9kZWwuZmEyLnIsIGZ1bmN0aW9uIChkZikgbXV0YXRlKGRmLCBjb20udmFyID0gMSAtIHVuaXF1ZW5lc3MpKSwKICAgICAgICAgbW9kZWwuZmEzLnIgPSBtYXAobW9kZWwuZmEzLnIsIGZ1bmN0aW9uIChkZikgbXV0YXRlKGRmLCBjb20udmFyID0gMSAtIHVuaXF1ZW5lc3MpKSkgJT4lIAogIG11dGF0ZShtZmEuY29vcmQgPSBtYXAobW9kZWwubWZhLGZ1bmN0aW9uKG1mYSkgbWZhJHF1YW50aS52YXIkY29vcmRbLDE6M10pKQoKIyBjaGVjayB0aGUgZGF0YQp0ZXRyYXBvZF9uZXN0ZWQKYGBgCgojIyBNYW1tYWxzIHsudGFic2V0fQoKIyMjIE11bHRpcGxlIEZhY3RvciBBbmFseXNpcyAoTUZBKQoKQ3JlYXRlIHRoZSBzdWJzZXQgZGF0YXNldAoKYGBge3J9Cm1hbW1hbHM8LSB0ZXRyYXBvZF9uZXN0ZWQgJT4lIAogIGZpbHRlcihDbGFzcyA9PSAiTWFtbWFsaWEiKQpgYGAKCkNoZWNrIHRoZSBwZXJjZW50YWdlIGZvciBlYWNoIGF4aXMgaW4gdGhlIE1GQSAKYGBge3J9Cm1hcChtYW1tYWxzJG1vZGVsLm1mYSx+ZnZpel9zY3JlZXBsb3QoLikpCmBgYAoKV2Ugc2VlIHRoYXQgdGhlIGZpcnN0IGRpbWVudGlvbiBleHBsYWluIG1vc3Qgb2YgdGhlIHZhcmlhdGlvbiBzbyB3ZSB3aWxsIHBsb3QgdGhlIGZpcnN0IGFuZCB0aGUgc2Vjb25kLgpOb3cgd2Ugd2lsbCBleHBsb3JlIHRoZSByZXN1bHRzLiAKCkZpcnN0IGxldHMgc2VlIGhvdyB0aGV5IGRpc3BlcnNlIGluIHNwYWNlCmBgYHtyfQptYXAobWFtbWFscyRtb2RlbC5tZmEsfmZ2aXpfbWZhX3ZhciguLCAicXVhbnRpLnZhciIsIHBhbGV0dGUgPSAiamNvIiwgCiAgICAgICAgICAgICBjb2wudmFyLnN1cCA9ICJ2aW9sZXQiLCByZXBlbCA9IFRSVUUsCiAgICAgICAgICAgICBnZW9tID0gYygicG9pbnQiLCAidGV4dCIpLCBsZWdlbmQgPSAibm9uZSIsdGl0bGUgPSAiTWFtbWFscyIpKQpgYGAKCkV4cGxvcmUgdGhlIGNvbnRyaWJ1dGlvbiBvZiBlYWNoIHRyYWl0IHRvIHRoZSBheGVzCmBgYHtyfQojdGhlIGNvbnRyaWJ1dGlvbiBvZiB0aGUgZmlyc3QgYXhpcwpwbTE8LSBtYXAobWFtbWFscyRtb2RlbC5tZmEsfmZ2aXpfY29udHJpYiguLCAiZ3JvdXAiLCBheGVzID0gMSx0aXRsZT0gIkNvbnRyaWJ1dGlvbiBvZiB0cmFpdHMgdG8gZmlyc3QgYXhpcy1tYW1tYWxzIikpCnBtMjwtIG1hcChtYW1tYWxzJG1vZGVsLm1mYSx+ZnZpel9jb250cmliKC4sICJncm91cCIsIGF4ZXMgPSAyLHRpdGxlPSAiQ29udHJpYnV0aW9uIG9mIHRyYWl0cyB0byBzZWNvbmQgYXhpcy1tYW1tYWxzIikpCmdtMTwtIHBsb3RfZ3JpZChwbTFbWzFdXSxwbTJbWzFdXSxsYWJlbHMgPSBjKCJBIiwiQiIpKQpnbTEKCmBgYAoKUGxvdCBlYWNoIHBvaW50IGFuZCBjb2xvciBpdCBiYXNlZCBvbiBpdHMgcXVhbGl0eSBvZiByZXByZXNlbnRhdGlvbiAKYGBge3J9Cm1hcChtYW1tYWxzJG1vZGVsLm1mYSx+ZnZpel9tZmFfaW5kKC4sIGNvbC5pbmQgPSAiY29zMiIsCiAgICAgICAgICAgICBncmFkaWVudC5jb2xzID0gYygiIzAwQUZCQiIsICIjRTdCODAwIiwgIiNGQzRFMDciKSwKICAgICAgICAgICAgIHJlcGVsID0gVFJVRSxsYWJlbCA9ICJub25lIikpCmBgYAoKCiMjIyBGYWN0b3IgQW5hbHlzaXMgd2l0aCBmYWN0YW5hbCBmdW5jdGlvbgoKIyMjIyBFeHBsb3JhdG9yeSBwb3dlcgoKV2UgY2FuIHNlZSB0aGF0IGluIGFsbCB0aGUgZmFjdG9ycyBpdCdzIHF1aXRlIHN0cm9uZyBleHBsb3JhdG9yeSBwb3dlci4KV2UgY2FuIHVzZSB0aGUgcGFyYWxsZWwgYW5hbHlzaXMgdG8gc2VlIGhvdyBtYW55IGZhY3RvcnMgd2Ugc2hvdWxkIHVzZS4gWW91IHNlZSB0aGF0IGJ5IGxvb2tpbmcgYXQgd2hlcmUgdGhlIGJsdWUgbGluZSAodGhlIGFjdHVhbCBkYXRhKSBicmVha3MgYW5kIHdoZXJlIHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gdGhlIGJsdWUgbGluZSBhbmQgdGhlIHJlZCBsaW5lIChzaW11bGF0ZWQgZGF0YSkgaXMgdGhlIHNtYWxsZXN0LiBCYXNlZCBvbiB0aGlzIHRocmVlIG1pZ2h0IGJlIG1vcmUgc3V0aWJsZSBidXQgaXQgaGFzIDAgZGVncmVlcyBvZiBmcmVlZG9tIHNvIHdlIHdpbGwgdGFrZSAqKlR3byBGYWN0b3JzKiouIAoKYGBge3J9CnBhcmFsbGVsIDwtIGZhLnBhcmFsbGVsKG1hbW1hbHMkZGF0YVtbMV1dLCBmbSA9ICdtbCcsIGZhID0gJ2ZhJykKYGBgCgoKKipUaGUgcmVzdWx0cyBmb3IgVGhyZWUgZmFjdG9ycyoqCgpUaGUgY29tbW9uIHZhcmlhbmNlIChjb2x1bW4gY29tLnZhcikgc2hvd3MgaG93IG11Y2ggb2YgdGhlIHZhcmlhbmNlIGlzIHNoYXJlZCBiZXR3ZWVuIGEgc3BlY2lmaWMgdmFyaWFibGUgYW5kIHRoZSByZXN0IG9mIHRoZSB2YXJpYWJsZXMuIFRoZSBsYXJnZXIgdGhlIG51bWJlciB0aGUgbW9yZSBpbmZvcm1hdGl2ZSB0aGUgdmFyaWFibGUuCgpgYGB7cn0Ka25pdHI6OmthYmxlKHByaW50KG1hbW1hbHMkbW9kZWwuZmEyLnIpKQpgYGAKCiMjIyMgRmFjdG9yIGFuYWx5c2lzIHBsb3QKCmBgYHtyfQpnZ3Bsb3QobWFtbWFscyRtb2RlbC5mYTIucltbMV1dLGFlcyhmbDEsZmwyKSkrCiAgdGhlbWVfZ2VvbWV0cnkobWFtbWFscyRtb2RlbC5mYTIucltbMV1dJGZsMSxtYW1tYWxzJG1vZGVsLmZhMi5yW1sxXV0kZmwyKSsKICBnZW9tX3BvaW50KCkrCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbD12YXJpYWJsZSksaGp1c3Q9MC41LCB2anVzdD0tMSkKYGBgCgojIyBCaXJkcyB7LnRhYnNldH0KCiMjIyBNdWx0aXBsZSBGYWN0b3IgQW5hbHlzaXMgKE1GQSkKCkNyZWF0ZSB0aGUgc3Vic2V0IGRhdGFzZXQKCmBgYHtyfQpiaXJkczwtIHRldHJhcG9kX25lc3RlZCAlPiUgCiAgZmlsdGVyKENsYXNzID09ICJBdmVzIikKYGBgCgpDaGVjayB0aGUgcGVyY2VudGFnZSBmb3IgZWFjaCBheGlzIGluIHRoZSBNRkEgCmBgYHtyfQptYXAoYmlyZHMkbW9kZWwubWZhLH5mdml6X3NjcmVlcGxvdCguKSkKYGBgCgpXZSBzZWUgdGhhdCB0aGUgZmlyc3QgZGltZW50aW9uIGV4cGxhaW4gbW9zdCBvZiB0aGUgdmFyaWF0aW9uIHNvIHdlIHdpbGwgcGxvdCB0aGUgZmlyc3QgYW5kIHRoZSBzZWNvbmQuCk5vdyB3ZSB3aWxsIGV4cGxvcmUgdGhlIHJlc3VsdHMuIAoKRmlyc3QgbGV0cyBzZWUgaG93IHRoZXkgZGlzcGVyc2UgaW4gc3BhY2UKYGBge3J9Cm1hcChiaXJkcyRtb2RlbC5tZmEsfmZ2aXpfbWZhX3ZhciguLCAicXVhbnRpLnZhciIsIHBhbGV0dGUgPSAiamNvIiwgCiAgICAgICAgICAgICBjb2wudmFyLnN1cCA9ICJ2aW9sZXQiLCByZXBlbCA9IFRSVUUsCiAgICAgICAgICAgICBnZW9tID0gYygicG9pbnQiLCAidGV4dCIpLCBsZWdlbmQgPSAibm9uZSIsdGl0bGUgPSAiQmlyZHMiKSkKYGBgCgpFeHBsb3JlIHRoZSBjb250cmlidXRpb24gb2YgZWFjaCB0cmFpdCB0byB0aGUgYXhlcwpgYGB7cn0KI3RoZSBjb250cmlidXRpb24gb2YgdGhlIGZpcnN0IGF4aXMKcG0xPC0gbWFwKGJpcmRzJG1vZGVsLm1mYSx+ZnZpel9jb250cmliKC4sICJncm91cCIsIGF4ZXMgPSAxLHRpdGxlPSAiQ29udHJpYnV0aW9uIG9mIHRyYWl0cyB0byBmaXJzdCBheGlzLW1hbW1hbHMiKSkKcG0yPC0gbWFwKGJpcmRzJG1vZGVsLm1mYSx+ZnZpel9jb250cmliKC4sICJncm91cCIsIGF4ZXMgPSAyLHRpdGxlPSAiQ29udHJpYnV0aW9uIG9mIHRyYWl0cyB0byBzZWNvbmQgYXhpcy1tYW1tYWxzIikpCmdtMTwtIHBsb3RfZ3JpZChwbTFbWzFdXSxwbTJbWzFdXSxsYWJlbHMgPSBjKCJBIiwiQiIpKQpnbTEKCmBgYAoKUGxvdCBlYWNoIHBvaW50IGFuZCBjb2xvciBpdCBiYXNlZCBvbiBpdHMgcXVhbGl0eSBvZiByZXByZXNlbnRhdGlvbiAKYGBge3J9Cm1hcChiaXJkcyRtb2RlbC5tZmEsfmZ2aXpfbWZhX2luZCguLCBjb2wuaW5kID0gImNvczIiLAogICAgICAgICAgICAgZ3JhZGllbnQuY29scyA9IGMoIiMwMEFGQkIiLCAiI0U3QjgwMCIsICIjRkM0RTA3IiksCiAgICAgICAgICAgICByZXBlbCA9IFRSVUUsbGFiZWwgPSAibm9uZSIpKQpgYGAKCgojIyMgRmFjdG9yIEFuYWx5c2lzIHdpdGggZmFjdGFuYWwgZnVuY3Rpb24KCiMjIyMgRXhwbG9yYXRvcnkgcG93ZXIKCldlIGNhbiBzZWUgdGhhdCBpbiBhbGwgdGhlIGZhY3RvcnMgaXQncyBxdWl0ZSBzdHJvbmcgZXhwbG9yYXRvcnkgcG93ZXIuCldlIGNhbiB1c2UgdGhlIHBhcmFsbGVsIGFuYWx5c2lzIHRvIHNlZSBob3cgbWFueSBmYWN0b3JzIHdlIHNob3VsZCB1c2UuIEluIG91ciBjYXNlIGl0J3MgKipUd28gRmFjdG9ycyoqCgpgYGB7cn0KcGFyYWxsZWwgPC0gZmEucGFyYWxsZWwoYmlyZHMkZGF0YVtbMV1dLCBmbSA9ICdtbCcsIGZhID0gJ2ZhJykKYGBgCgoKKipUaGUgcmVzdWx0cyBmb3IgVHdvIGZhY3RvcnMqKgoKVGhlIGNvbW1vbiB2YXJpYW5jZSAoY29sdW1uIGNvbS52YXIpIHNob3dzIGhvdyBtdWNoIG9mIHRoZSB2YXJpYW5jZSBpcyBzaGFyZWQgYmV0d2VlbiBhIHNwZWNpZmljIHZhcmlhYmxlIGFuZCB0aGUgcmVzdCBvZiB0aGUgdmFyaWFibGVzLiBUaGUgbGFyZ2VyIHRoZSBudW1iZXIgdGhlIG1vcmUgaW5mb3JtYXRpdmUgdGhlIHZhcmlhYmxlLgoKYGBge3J9CmtuaXRyOjprYWJsZShwcmludChiaXJkcyRtb2RlbC5mYTIucikpCmBgYAoKIyMjIyBGYWN0b3IgYW5hbHlzaXMgcGxvdAoKYGBge3J9CmdncGxvdChiaXJkcyRtb2RlbC5mYTIucltbMV1dLGFlcyhmbDEsZmwyKSkrCiAgdGhlbWVfZ2VvbWV0cnkoYmlyZHMkbW9kZWwuZmEyLnJbWzFdXSRmbDEsYmlyZHMkbW9kZWwuZmEyLnJbWzFdXSRmbDIpKwogIGdlb21fcG9pbnQoKSsKICBnZW9tX3RleHQoYWVzKGxhYmVsPXZhcmlhYmxlKSxoanVzdD0wLjUsIHZqdXN0PS0xKQpgYGAKCgojIyBSZXB0aWxlcyB7LnRhYnNldH0KCiMjIyBNdWx0aXBsZSBGYWN0b3IgQW5hbHlzaXMgKE1GQSkKCkNyZWF0ZSB0aGUgc3Vic2V0IGRhdGFzZXQKCmBgYHtyfQpyZXB0aWxlczwtIHRldHJhcG9kX25lc3RlZCAlPiUgCiAgZmlsdGVyKENsYXNzID09ICJSZXB0aWxpYSIpCmBgYAoKQ2hlY2sgdGhlIHBlcmNlbnRhZ2UgZm9yIGVhY2ggYXhpcyBpbiB0aGUgTUZBIApgYGB7cn0KbWFwKHJlcHRpbGVzJG1vZGVsLm1mYSx+ZnZpel9zY3JlZXBsb3QoLikpCmBgYAoKV2Ugc2VlIHRoYXQgdGhlIGZpcnN0IGRpbWVudGlvbiBleHBsYWluIG1vc3Qgb2YgdGhlIHZhcmlhdGlvbiBzbyB3ZSB3aWxsIHBsb3QgdGhlIGZpcnN0IGFuZCB0aGUgc2Vjb25kLgpOb3cgd2Ugd2lsbCBleHBsb3JlIHRoZSByZXN1bHRzLiAKCkZpcnN0IGxldHMgc2VlIGhvdyB0aGV5IGRpc3BlcnNlIGluIHNwYWNlCmBgYHtyfQptYXAocmVwdGlsZXMkbW9kZWwubWZhLH5mdml6X21mYV92YXIoLiwgInF1YW50aS52YXIiLCBwYWxldHRlID0gImpjbyIsIAogICAgICAgICAgICAgY29sLnZhci5zdXAgPSAidmlvbGV0IiwgcmVwZWwgPSBUUlVFLAogICAgICAgICAgICAgZ2VvbSA9IGMoInBvaW50IiwgInRleHQiKSwgbGVnZW5kID0gIm5vbmUiLHRpdGxlID0gIlJlcHRpbGVzIikpCmBgYAoKRXhwbG9yZSB0aGUgY29udHJpYnV0aW9uIG9mIGVhY2ggdHJhaXQgdG8gdGhlIGF4ZXMKYGBge3J9CiN0aGUgY29udHJpYnV0aW9uIG9mIHRoZSBmaXJzdCBheGlzCnBtMTwtIG1hcChyZXB0aWxlcyRtb2RlbC5tZmEsfmZ2aXpfY29udHJpYiguLCAiZ3JvdXAiLCBheGVzID0gMSx0aXRsZT0gIkNvbnRyaWJ1dGlvbiBvZiB0cmFpdHMgdG8gZmlyc3QgYXhpcy1tYW1tYWxzIikpCnBtMjwtIG1hcChyZXB0aWxlcyRtb2RlbC5tZmEsfmZ2aXpfY29udHJpYiguLCAiZ3JvdXAiLCBheGVzID0gMix0aXRsZT0gIkNvbnRyaWJ1dGlvbiBvZiB0cmFpdHMgdG8gc2Vjb25kIGF4aXMtbWFtbWFscyIpKQpnbTE8LSBwbG90X2dyaWQocG0xW1sxXV0scG0yW1sxXV0sbGFiZWxzID0gYygiQSIsIkIiKSkKZ20xCgpgYGAKClBsb3QgZWFjaCBwb2ludCBhbmQgY29sb3IgaXQgYmFzZWQgb24gaXRzIHF1YWxpdHkgb2YgcmVwcmVzZW50YXRpb24gCmBgYHtyfQptYXAocmVwdGlsZXMkbW9kZWwubWZhLH5mdml6X21mYV9pbmQoLiwgY29sLmluZCA9ICJjb3MyIiwKICAgICAgICAgICAgIGdyYWRpZW50LmNvbHMgPSBjKCIjMDBBRkJCIiwgIiNFN0I4MDAiLCAiI0ZDNEUwNyIpLAogICAgICAgICAgICAgcmVwZWwgPSBUUlVFLGxhYmVsID0gIm5vbmUiKSkKYGBgCgoKIyMjIEZhY3RvciBBbmFseXNpcyB3aXRoIGZhY3RhbmFsIGZ1bmN0aW9uCgojIyMjIEV4cGxvcmF0b3J5IHBvd2VyCgpXZSBjYW4gc2VlIHRoYXQgaW4gYWxsIHRoZSBmYWN0b3JzIGl0J3MgcXVpdGUgc3Ryb25nIGV4cGxvcmF0b3J5IHBvd2VyLgpXZSBjYW4gdXNlIHRoZSBwYXJhbGxlbCBhbmFseXNpcyB0byBzZWUgaG93IG1hbnkgZmFjdG9ycyB3ZSBzaG91bGQgdXNlLiBJbiBvdXIgY2FzZSBpdCdzICoqVHdvIEZhY3RvcnMqKgoKYGBge3J9CnBhcmFsbGVsIDwtIGZhLnBhcmFsbGVsKHJlcHRpbGVzJGRhdGFbWzFdXSwgZm0gPSAnbWwnLCBmYSA9ICdmYScpCmBgYAoKCioqVGhlIHJlc3VsdHMgZm9yIFR3byBmYWN0b3JzKioKClRoZSBjb21tb24gdmFyaWFuY2UgKGNvbHVtbiBjb20udmFyKSBzaG93cyBob3cgbXVjaCBvZiB0aGUgdmFyaWFuY2UgaXMgc2hhcmVkIGJldHdlZW4gYSBzcGVjaWZpYyB2YXJpYWJsZSBhbmQgdGhlIHJlc3Qgb2YgdGhlIHZhcmlhYmxlcy4gVGhlIGxhcmdlciB0aGUgbnVtYmVyIHRoZSBtb3JlIGluZm9ybWF0aXZlIHRoZSB2YXJpYWJsZS4KCmBgYHtyfQprbml0cjo6a2FibGUocHJpbnQocmVwdGlsZXMkbW9kZWwuZmEyLnIpKQpgYGAKCiMjIyMgRmFjdG9yIGFuYWx5c2lzIHBsb3QKCmBgYHtyfQpnZ3Bsb3QocmVwdGlsZXMkbW9kZWwuZmEyLnJbWzFdXSxhZXMoZmwxLGZsMikpKwogIHRoZW1lX2dlb21ldHJ5KHJlcHRpbGVzJG1vZGVsLmZhMi5yW1sxXV0kZmwxLHJlcHRpbGVzJG1vZGVsLmZhMi5yW1sxXV0kZmwyKSsKICBnZW9tX3BvaW50KCkrCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbD12YXJpYWJsZSksaGp1c3Q9MC41LCB2anVzdD0tMSkKYGBgCgojIyBBbXBoaWJpYW5zIHsudGFic2V0fQoKIyMjIE11bHRpcGxlIEZhY3RvciBBbmFseXNpcyAoTUZBKQoKQ3JlYXRlIHRoZSBzdWJzZXQgZGF0YXNldAoKYGBge3J9CmFtcGg8LSB0ZXRyYXBvZF9uZXN0ZWQgJT4lIAogIGZpbHRlcihDbGFzcyA9PSAiQW1waGliaWEiKQpgYGAKCkNoZWNrIHRoZSBwZXJjZW50YWdlIGZvciBlYWNoIGF4aXMgaW4gdGhlIE1GQSAKYGBge3J9Cm1hcChhbXBoJG1vZGVsLm1mYSx+ZnZpel9zY3JlZXBsb3QoLikpCmBgYAoKV2Ugc2VlIHRoYXQgdGhlIGZpcnN0IGRpbWVudGlvbiBleHBsYWluIG1vc3Qgb2YgdGhlIHZhcmlhdGlvbiBzbyB3ZSB3aWxsIHBsb3QgdGhlIGZpcnN0IGFuZCB0aGUgc2Vjb25kLgpOb3cgd2Ugd2lsbCBleHBsb3JlIHRoZSByZXN1bHRzLiAKCkZpcnN0IGxldHMgc2VlIGhvdyB0aGV5IGRpc3BlcnNlIGluIHNwYWNlCmBgYHtyfQptYXAoYW1waCRtb2RlbC5tZmEsfmZ2aXpfbWZhX3ZhciguLCAicXVhbnRpLnZhciIsIHBhbGV0dGUgPSAiamNvIiwgCiAgICAgICAgICAgICBjb2wudmFyLnN1cCA9ICJ2aW9sZXQiLCByZXBlbCA9IFRSVUUsCiAgICAgICAgICAgICBnZW9tID0gYygicG9pbnQiLCAidGV4dCIpLCBsZWdlbmQgPSAibm9uZSIsdGl0bGUgPSAiQW1waGliaWFucyIpKQpgYGAKCkV4cGxvcmUgdGhlIGNvbnRyaWJ1dGlvbiBvZiBlYWNoIHRyYWl0IHRvIHRoZSBheGVzCmBgYHtyfQojdGhlIGNvbnRyaWJ1dGlvbiBvZiB0aGUgZmlyc3QgYXhpcwpwbTE8LSBtYXAoYW1waCRtb2RlbC5tZmEsfmZ2aXpfY29udHJpYiguLCAiZ3JvdXAiLCBheGVzID0gMSx0aXRsZT0gIkNvbnRyaWJ1dGlvbiBvZiB0cmFpdHMgdG8gZmlyc3QgYXhpcy1tYW1tYWxzIikpCnBtMjwtIG1hcChhbXBoJG1vZGVsLm1mYSx+ZnZpel9jb250cmliKC4sICJncm91cCIsIGF4ZXMgPSAyLHRpdGxlPSAiQ29udHJpYnV0aW9uIG9mIHRyYWl0cyB0byBzZWNvbmQgYXhpcy1tYW1tYWxzIikpCmdtMTwtIHBsb3RfZ3JpZChwbTFbWzFdXSxwbTJbWzFdXSxsYWJlbHMgPSBjKCJBIiwiQiIpKQpnbTEKCmBgYAoKUGxvdCBlYWNoIHBvaW50IGFuZCBjb2xvciBpdCBiYXNlZCBvbiBpdHMgcXVhbGl0eSBvZiByZXByZXNlbnRhdGlvbiAKYGBge3J9Cm1hcChhbXBoJG1vZGVsLm1mYSx+ZnZpel9tZmFfaW5kKC4sIGNvbC5pbmQgPSAiY29zMiIsCiAgICAgICAgICAgICBncmFkaWVudC5jb2xzID0gYygiIzAwQUZCQiIsICIjRTdCODAwIiwgIiNGQzRFMDciKSwKICAgICAgICAgICAgIHJlcGVsID0gVFJVRSxsYWJlbCA9ICJub25lIikpCmBgYAoKCiMjIyBGYWN0b3IgQW5hbHlzaXMgd2l0aCBmYWN0YW5hbCBmdW5jdGlvbgoKIyMjIyBFeHBsb3JhdG9yeSBwb3dlcgoKV2UgY2FuIHNlZSB0aGF0IGluIGFsbCB0aGUgZmFjdG9ycyBpdCdzIHF1aXRlIHN0cm9uZyBleHBsb3JhdG9yeSBwb3dlci4KV2UgY2FuIHVzZSB0aGUgcGFyYWxsZWwgYW5hbHlzaXMgdG8gc2VlIGhvdyBtYW55IGZhY3RvcnMgd2Ugc2hvdWxkIHVzZS4gSW4gb3VyIGNhc2UgaXQncyAqKlR3byBGYWN0b3JzKioKCmBgYHtyfQpwYXJhbGxlbCA8LSBmYS5wYXJhbGxlbChhbXBoJGRhdGFbWzFdXSwgZm0gPSAnbWwnLCBmYSA9ICdmYScpCmBgYAoKCioqVGhlIHJlc3VsdHMgZm9yIFR3byBmYWN0b3JzKioKClRoZSBjb21tb24gdmFyaWFuY2UgKGNvbHVtbiBjb20udmFyKSBzaG93cyBob3cgbXVjaCBvZiB0aGUgdmFyaWFuY2UgaXMgc2hhcmVkIGJldHdlZW4gYSBzcGVjaWZpYyB2YXJpYWJsZSBhbmQgdGhlIHJlc3Qgb2YgdGhlIHZhcmlhYmxlcy4gVGhlIGxhcmdlciB0aGUgbnVtYmVyIHRoZSBtb3JlIGluZm9ybWF0aXZlIHRoZSB2YXJpYWJsZS4KCkluIGhlcmUgeW91IHNlZSB0aGF0IHNvbWUgb2YgdGhlIHZhcmlhYmxlcyBkb24ndCBhZGQgbXVjaCB0byB0aGUgbW9kZWwgKGNvbS52YXIgaXMgbG93KQoKYGBge3J9CmtuaXRyOjprYWJsZShwcmludChhbXBoJG1vZGVsLmZhMi5yKSkKYGBgCgojIyMjIEZhY3RvciBhbmFseXNpcyBwbG90CgpgYGB7cn0KZ2dwbG90KGFtcGgkbW9kZWwuZmEyLnJbWzFdXSxhZXMoZmwxLGZsMikpKwogIHRoZW1lX2dlb21ldHJ5KGFtcGgkbW9kZWwuZmEyLnJbWzFdXSRmbDEsYW1waCRtb2RlbC5mYTIucltbMV1dJGZsMikrCiAgZ2VvbV9wb2ludCgpKwogIGdlb21fdGV4dChhZXMobGFiZWw9dmFyaWFibGUpLGhqdXN0PTAuNSwgdmp1c3Q9LTEpCmBgYAoKCiMjIEFsbCB0ZXRyYXBvZHMgey50YWJzZXR9CgojIyMgTXVsdGlwbGUgRmFjdG9yIEFuYWx5c2lzIChNRkEpCgpDcmVhdGUgdGhlIHN1YnNldCBkYXRhc2V0CgpgYGB7cn0KYWxsLnRldHJhcG9kczwtIHRldHJhcG9kX25lc3RlZCAlPiUgCiAgZmlsdGVyKENsYXNzID09ICJUZXRyYXBvZHMiKQpgYGAKCkNoZWNrIHRoZSBwZXJjZW50YWdlIGZvciBlYWNoIGF4aXMgaW4gdGhlIE1GQSAKYGBge3J9Cm1hcChhbGwudGV0cmFwb2RzJG1vZGVsLm1mYSx+ZnZpel9zY3JlZXBsb3QoLikpCmBgYAoKV2Ugc2VlIHRoYXQgdGhlIGZpcnN0IGRpbWVudGlvbiBleHBsYWluIG1vc3Qgb2YgdGhlIHZhcmlhdGlvbiBzbyB3ZSB3aWxsIHBsb3QgdGhlIGZpcnN0IGFuZCB0aGUgc2Vjb25kLgpOb3cgd2Ugd2lsbCBleHBsb3JlIHRoZSByZXN1bHRzLiAKCkZpcnN0IGxldHMgc2VlIGhvdyB0aGV5IGRpc3BlcnNlIGluIHNwYWNlCmBgYHtyfQptYXAoYWxsLnRldHJhcG9kcyRtb2RlbC5tZmEsfmZ2aXpfbWZhX3ZhciguLCAicXVhbnRpLnZhciIsIHBhbGV0dGUgPSAiamNvIiwgCiAgICAgICAgICAgICBjb2wudmFyLnN1cCA9ICJ2aW9sZXQiLCByZXBlbCA9IFRSVUUsCiAgICAgICAgICAgICBnZW9tID0gYygicG9pbnQiLCAidGV4dCIpLCBsZWdlbmQgPSAibm9uZSIsdGl0bGUgPSAiQWxsIHRldHJhcG9kcyIpKQpgYGAKCkV4cGxvcmUgdGhlIGNvbnRyaWJ1dGlvbiBvZiBlYWNoIHRyYWl0IHRvIHRoZSBheGVzCmBgYHtyfQojdGhlIGNvbnRyaWJ1dGlvbiBvZiB0aGUgZmlyc3QgYXhpcwpwbTE8LSBtYXAoYWxsLnRldHJhcG9kcyRtb2RlbC5tZmEsfmZ2aXpfY29udHJpYiguLCAiZ3JvdXAiLCBheGVzID0gMSx0aXRsZT0gIkNvbnRyaWJ1dGlvbiBvZiB0cmFpdHMgdG8gZmlyc3QgYXhpcy1tYW1tYWxzIikpCnBtMjwtIG1hcChhbGwudGV0cmFwb2RzJG1vZGVsLm1mYSx+ZnZpel9jb250cmliKC4sICJncm91cCIsIGF4ZXMgPSAyLHRpdGxlPSAiQ29udHJpYnV0aW9uIG9mIHRyYWl0cyB0byBzZWNvbmQgYXhpcy1tYW1tYWxzIikpCmdtMTwtIHBsb3RfZ3JpZChwbTFbWzFdXSxwbTJbWzFdXSxsYWJlbHMgPSBjKCJBIiwiQiIpKQpnbTEKCmBgYAoKUGxvdCBlYWNoIHBvaW50IGFuZCBjb2xvciBpdCBiYXNlZCBvbiBpdHMgcXVhbGl0eSBvZiByZXByZXNlbnRhdGlvbiAKYGBge3J9Cm1hcChhbGwudGV0cmFwb2RzJG1vZGVsLm1mYSx+ZnZpel9tZmFfaW5kKC4sIGNvbC5pbmQgPSAiY29zMiIsCiAgICAgICAgICAgICBncmFkaWVudC5jb2xzID0gYygiIzAwQUZCQiIsICIjRTdCODAwIiwgIiNGQzRFMDciKSwKICAgICAgICAgICAgIHJlcGVsID0gVFJVRSxsYWJlbCA9ICJub25lIikpCmBgYAoKCiMjIyBGYWN0b3IgQW5hbHlzaXMgd2l0aCBmYWN0YW5hbCBmdW5jdGlvbgoKIyMjIyBFeHBsb3JhdG9yeSBwb3dlcgoKV2UgY2FuIHNlZSB0aGF0IGluIGFsbCB0aGUgZmFjdG9ycyBpdCdzIHF1aXRlIHN0cm9uZyBleHBsb3JhdG9yeSBwb3dlci4KV2UgY2FuIHVzZSB0aGUgcGFyYWxsZWwgYW5hbHlzaXMgdG8gc2VlIGhvdyBtYW55IGZhY3RvcnMgd2Ugc2hvdWxkIHVzZS4gSW4gb3VyIGNhc2UgaXQncyAqKlR3byBGYWN0b3JzKioKCmBgYHtyfQpwYXJhbGxlbCA8LSBmYS5wYXJhbGxlbChhbGwudGV0cmFwb2RzJGRhdGFbWzFdXSwgZm0gPSAnbWwnLCBmYSA9ICdmYScpCmBgYAoKCioqVGhlIHJlc3VsdHMgZm9yIFR3byBmYWN0b3JzKioKClRoZSBjb21tb24gdmFyaWFuY2UgKGNvbHVtbiBjb20udmFyKSBzaG93cyBob3cgbXVjaCBvZiB0aGUgdmFyaWFuY2UgaXMgc2hhcmVkIGJldHdlZW4gYSBzcGVjaWZpYyB2YXJpYWJsZSBhbmQgdGhlIHJlc3Qgb2YgdGhlIHZhcmlhYmxlcy4gVGhlIGxhcmdlciB0aGUgbnVtYmVyIHRoZSBtb3JlIGluZm9ybWF0aXZlIHRoZSB2YXJpYWJsZS4KCmBgYHtyfQprbml0cjo6a2FibGUocHJpbnQoYWxsLnRldHJhcG9kcyRtb2RlbC5mYTIucikpCmBgYAoKIyMjIyBGYWN0b3IgYW5hbHlzaXMgcGxvdAoKYGBge3J9CmdncGxvdChhbGwudGV0cmFwb2RzJG1vZGVsLmZhMi5yW1sxXV0sYWVzKGZsMSxmbDIpKSsKICB0aGVtZV9nZW9tZXRyeShhbGwudGV0cmFwb2RzJG1vZGVsLmZhMi5yW1sxXV0kZmwxLGFsbC50ZXRyYXBvZHMkbW9kZWwuZmEyLnJbWzFdXSRmbDIpKwogIGdlb21fcG9pbnQoKSsKICBnZW9tX3RleHQoYWVzKGxhYmVsPXZhcmlhYmxlKSxoanVzdD0wLjUsIHZqdXN0PS0xKQpgYGAKCg==